// 引入Express框架，用于创建Web服务器
const express = require('express');
// 引入Multer中间件，用于处理文件上传
const multer = require('multer');
// 引入路径模块，用于处理文件路径
const path = require('path');
// 引入文件系统模块，用于文件操作
const fs = require('fs');
// 引入简单图像分类器模块
const SimpleImageClassifier = require('../models/simple_classifier');

// 创建Express应用实例
const app = express();
// 设置服务器端口号
const port = 3003;

// 配置multer中间件用于文件上传处理
const upload = multer({ 
  dest: 'uploads/',  // 设置上传文件的临时存储目录
  fileFilter: (req, file, cb) => {  // 文件过滤器，只允许图片文件
    if (file.mimetype.startsWith('image/')) {  // 检查MIME类型是否为图片
      cb(null, true);   // 允许上传
    } else {
      cb(new Error('只允许上传图片文件'));  // 拒绝非图片文件
    }
  }
});

// 全局分类器实例变量
let classifier = null;

/**
 * 初始化模型的异步函数
 */
async function initModel() {
  try {
    // 创建简单图像分类器实例
    classifier = new SimpleImageClassifier();
    
    // 优先加载修复版模型
    const fixedModelPath = path.join(__dirname, '../../models/simple_model_fixed.json');
    const originalModelPath = path.join(__dirname, '../../models/simple_model.json');
    
    if (fs.existsSync(fixedModelPath)) {
      classifier.loadModel(fixedModelPath);
      console.log('✅ 修复版模型加载成功 - 已解决"全是狗"问题');
    } else if (fs.existsSync(originalModelPath)) {
      classifier.loadModel(originalModelPath);
      console.log('⚠️ 原版模型加载成功 - 可能存在识别偏向');
    } else {
      console.log('❌ 未找到模型文件，请先训练模型');
      console.log('运行: node src/models/simple_classifier.js');
    }
  } catch (error) {
    console.error('❌ 模型加载失败:', error);
  }
}

// 确保uploads目录存在，如果不存在则创建
if (!fs.existsSync('uploads')) {
  fs.mkdirSync('uploads');
}

// 设置静态文件服务，允许访问uploads目录中的文件
app.use('/uploads', express.static('uploads'));

/**
 * 主页路由处理器
 * 返回完整的HTML页面，包含文件上传和预测功能
 */
app.get('/', (req, res) => {
  // 发送包含完整前端界面的HTML响应
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
        <title>猫狗识别系统</title>
        <meta charset="utf-8">
        <style>
            /* 页面整体样式：设置字体、布局和渐变背景 */
            body { 
                font-family: 'Microsoft YaHei', Arial, sans-serif; 
                max-width: 800px; 
                margin: 0 auto; 
                padding: 20px;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                min-height: 100vh;
            }
            /* 主容器样式：白色背景、圆角、阴影效果 */
            .container {
                background: white;
                border-radius: 15px;
                padding: 30px;
                box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            }
            /* 主标题样式：居中对齐、深色文字 */
            h1 {
                text-align: center;
                color: #333;
                margin-bottom: 10px;
            }
            /* 副标题样式：居中对齐、灰色文字 */
            .subtitle {
                text-align: center;
                color: #666;
                margin-bottom: 30px;
            }
            /* 上传区域样式：虚线边框、居中文本、悬停效果 */
            .upload-area { 
                border: 3px dashed #ddd; 
                padding: 40px; 
                text-align: center; 
                margin: 20px 0;
                border-radius: 10px;
                transition: all 0.3s ease;
                cursor: pointer;
            }
            /* 上传区域悬停效果：改变边框颜色和背景 */
            .upload-area:hover {
                border-color: #667eea;
                background: #f8f9ff;
            }
            /* 拖拽悬停状态样式 */
            .upload-area.dragover {
                border-color: #667eea;
                background: #f0f4ff;
            }
            /* 结果显示区域样式：渐变背景、左边框 */
            .result { 
                margin: 20px 0; 
                padding: 20px; 
                background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
                border-radius: 10px;
                border-left: 5px solid #667eea;
            }
            /* 图片预览样式：限制大小、居中显示、圆角阴影 */
            .preview { 
                max-width: 300px; 
                margin: 20px auto;
                display: block;
                border-radius: 10px;
                box-shadow: 0 5px 15px rgba(0,0,0,0.1);
            }
            /* 按钮样式：渐变背景、圆角、悬停效果 */
            button { 
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white; 
                padding: 12px 30px; 
                border: none; 
                border-radius: 25px; 
                cursor: pointer;
                font-size: 16px;
                font-weight: bold;
                transition: all 0.3s ease;
                display: block;
                margin: 20px auto;
            }
            /* 按钮悬停效果：向上移动、增加阴影 */
            button:hover { 
                transform: translateY(-2px);
                box-shadow: 0 5px 15px rgba(0,0,0,0.2);
            }
            /* 按钮禁用状态：降低透明度、禁用悬停效果 */
            button:disabled {
                opacity: 0.6;
                cursor: not-allowed;
                transform: none;
            }
            /* 加载动画样式：旋转的圆环 */
            .loading {
                display: inline-block;
                width: 20px;
                height: 20px;
                border: 3px solid #f3f3f3;
                border-top: 3px solid #667eea;
                border-radius: 50%;
                animation: spin 1s linear infinite;
                margin-right: 10px;
            }
            /* 旋转动画关键帧 */
            @keyframes spin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
            /* 置信度条背景样式 */
            .confidence-bar {
                background: #e0e0e0;
                border-radius: 10px;
                overflow: hidden;
                margin: 10px 0;
            }
            /* 置信度条填充样式：渐变背景、动画效果 */
            .confidence-fill {
                height: 20px;
                background: linear-gradient(90deg, #667eea, #764ba2);
                transition: width 0.5s ease;
                display: flex;
                align-items: center;
                justify-content: center;
                color: white;
                font-weight: bold;
                font-size: 12px;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <!-- 页面标题和描述 -->
            <h1>🐱🐶 AI猫狗识别系统</h1>
            <p class="subtitle">基于机器学习的图像分类技术</p>
            
            <!-- 文件上传表单 -->
            <form id="uploadForm" enctype="multipart/form-data">
                <div class="upload-area" id="uploadArea">
                    <!-- 隐藏的文件输入框 -->
                    <input type="file" id="imageFile" name="image" accept="image/*" required style="display: none;">
                    <div id="uploadText">
                        <p style="font-size: 18px; margin: 0;">📁 点击选择图片或拖拽到此处</p>
                        <p style="color: #999; margin: 10px 0 0 0;">支持 JPG、PNG 格式</p>
                    </div>
                </div>
                <!-- 提交按钮 -->
                <button type="submit" id="submitBtn">🔍 开始识别</button>
            </form>
            
            <!-- 图片预览区域 -->
            <div id="preview"></div>
            <!-- 识别结果显示区域 -->
            <div id="result"></div>
        </div>
        
        <script>
            // 获取页面元素的引用
            const uploadArea = document.getElementById('uploadArea');      // 上传区域
            const fileInput = document.getElementById('imageFile');        // 文件输入框
            const uploadForm = document.getElementById('uploadForm');      // 上传表单
            const submitBtn = document.getElementById('submitBtn');        // 提交按钮
            const previewDiv = document.getElementById('preview');         // 预览区域
            const resultDiv = document.getElementById('result');           // 结果区域
            
            // 点击上传区域时触发文件选择
            uploadArea.addEventListener('click', () => {
                fileInput.click();  // 触发隐藏的文件输入框
            });
            
            // 处理拖拽上传：拖拽悬停事件
            uploadArea.addEventListener('dragover', (e) => {
                e.preventDefault();  // 阻止默认行为
                uploadArea.classList.add('dragover');  // 添加悬停样式
            });
            
            // 处理拖拽离开事件
            uploadArea.addEventListener('dragleave', () => {
                uploadArea.classList.remove('dragover');  // 移除悬停样式
            });
            
            // 处理文件拖拽放置事件
            uploadArea.addEventListener('drop', (e) => {
                e.preventDefault();  // 阻止默认行为
                uploadArea.classList.remove('dragover');  // 移除悬停样式
                const files = e.dataTransfer.files;  // 获取拖拽的文件
                if (files.length > 0) {
                    fileInput.files = files;  // 设置文件输入框的文件
                    handleFileSelect();       // 处理文件选择
                }
            });
            
            // 监听文件输入框的变化事件
            fileInput.addEventListener('change', handleFileSelect);
            
            /**
             * 处理文件选择的函数
             */
            function handleFileSelect() {
                const file = fileInput.files[0];  // 获取选中的文件
                if (file) {
                    const reader = new FileReader();  // 创建文件读取器
                    reader.onload = (e) => {  // 文件读取完成后的回调
                        // 在预览区域显示图片
                        previewDiv.innerHTML = '<img src="' + e.target.result + '" class="preview" alt="预览图片">';
                    };
                    reader.readAsDataURL(file);  // 以DataURL格式读取文件
                }
            }
            
            // 监听表单提交事件
            uploadForm.addEventListener('submit', async (e) => {
                e.preventDefault();  // 阻止表单默认提交行为
                
                // 检查是否选择了文件
                if (!fileInput.files[0]) {
                    alert('请先选择图片！');
                    return;
                }
                
                // 创建FormData对象用于文件上传
                const formData = new FormData();
                formData.append('image', fileInput.files[0]);
                
                // 设置按钮为加载状态
                submitBtn.disabled = true;
                submitBtn.innerHTML = '<div class="loading"></div>识别中...';
                resultDiv.innerHTML = '';  // 清空之前的结果
                
                try {
                    // 发送POST请求到预测接口
                    const response = await fetch('/predict', {
                        method: 'POST',
                        body: formData
                    });
                    
                    // 解析JSON响应
                    const result = await response.json();
                    
                    if (result.success) {  // 如果预测成功
                        const confidence = result.probability * 100;  // 计算置信度百分比
                        const emoji = result.className === 'cat' ? '🐱' : '🐶';  // 选择对应的表情符号
                        const animal = result.className === 'cat' ? '猫咪' : '狗狗';  // 中文动物名称
                        
                        // 构建并显示结果HTML
                        resultDiv.innerHTML = 
                            '<div class="result">' +
                            '<h3 style="text-align: center; margin-top: 0;">' + emoji + ' 识别结果：' + animal + '</h3>' +
                            '<div class="confidence-bar">' +
                            '<div class="confidence-fill" style="width: ' + confidence + '%">' + confidence.toFixed(1) + '%</div>' +
                            '</div>' +
                            '<p style="text-align: center; margin: 15px 0;">置信度详情：</p>' +
                            '<div style="display: flex; justify-content: space-around;">' +
                            '<div style="text-align: center;"><strong>🐱 猫咪</strong><br>' + (result.probabilities.cat * 100).toFixed(1) + '%</div>' +
                            '<div style="text-align: center;"><strong>🐶 狗狗</strong><br>' + (result.probabilities.dog * 100).toFixed(1) + '%</div>' +
                            '</div>' +
                            '</div>';
                    } else {  // 如果预测失败
                        resultDiv.innerHTML = '<div class="result" style="border-left-color: #e74c3c;">❌ 识别失败：' + result.error + '</div>';
                    }
                } catch (error) {  // 如果请求出错
                    resultDiv.innerHTML = '<div class="result" style="border-left-color: #e74c3c;">❌ 请求失败：' + error.message + '</div>';
                } finally {  // 无论成功失败都要恢复按钮状态
                    submitBtn.disabled = false;
                    submitBtn.innerHTML = '🔍 开始识别';
                }
            });
        </script>
    </body>
    </html>
  `);
});

/**
 * 预测接口路由处理器
 * 处理POST请求，接收上传的图片并返回预测结果
 */
app.post('/predict', upload.single('image'), async (req, res) => {
  try {
    // 检查分类器是否已加载
    if (!classifier) {
      return res.json({ success: false, error: '模型未加载' });
    }
    
    // 检查是否上传了文件
    if (!req.file) {
      return res.json({ success: false, error: '未上传文件' });
    }
    
    // 打印处理信息
    console.log(`Processing uploaded image: ${req.file.originalname}`);
    
    // 使用分类器对上传的图片进行预测
    const prediction = await classifier.predict(req.file.path);
    
    // 删除临时上传文件，释放存储空间
    fs.unlinkSync(req.file.path);
    
    // 检查预测是否成功
    if (!prediction) {
      return res.json({ success: false, error: '图片处理失败' });
    }
    
    // 打印预测结果到控制台
    console.log(`Prediction: ${prediction.className} (${(prediction.probability * 100).toFixed(1)}%)`);
    
    // 返回成功的预测结果
    res.json({
      success: true,                        // 成功标志
      className: prediction.className,      // 类别名称
      class: prediction.class,              // 类别索引
      probability: prediction.probability,  // 预测概率
      probabilities: prediction.probabilities  // 详细概率分布
    });
    
  } catch (error) {
    // 如果预测过程中出错，打印错误并返回失败响应
    console.error('预测错误:', error);
    res.json({ success: false, error: error.message });
  }
});

/**
 * 启动服务器
 */
app.listen(port, async () => {
  // 打印服务器启动信息
  console.log(`🚀 猫狗识别服务器运行在 http://localhost:${port}`);
  console.log('正在加载模型...');
  // 异步初始化模型
  await initModel();
  console.log('✅ 服务器就绪，可以开始使用！');
});